/*
    Lontium LT8911EXB MIPI to EDP driver

    Copyright  (C)  2016 - 2017 Topband. Ltd.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be a reference
    to you, when you are integrating the Lontium's LT8911EXB IC into your system,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    General Public License for more details.

    Author: shenhaibo
    Version: 1.1.0
    Release Date: 2019/3/6
*/


#ifndef _LONTIUM_LT8911EXB_H_
#define _LONTIUM_LT8911EXB_H_

#include <linux/kernel.h>
#include <linux/hrtimer.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/proc_fs.h>
#include <linux/string.h>
#include <linux/uaccess.h>
#include <linux/vmalloc.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/regulator/consumer.h>
#include <linux/major.h>
#include <linux/kdev_t.h>
#include <linux/of_gpio.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/usb.h>
#include <linux/power_supply.h>

#define LT8911EXB_I2C_NAME      "lt8911exb"
#define LT8911EXB_DRIVER_VERSION  "1.0.0"

#define LT8911EXB_ADDR_LENGTH      1
#define I2C_MAX_TRANSFER_SIZE   255
#define RETRY_MAX_TIMES         3

//#define _EDP_Pattern_ // LT8911EX test pattern Output

#define _eDP_1G62_
//#define _eDP_2G7_
//#define _INT_En_

//#define _Msa_Active_Only_

#define _link_train_enable_

//*****************************************************//

//#define _1080P_eDP_Panel_
#define _1920x515_eDP_Panel_
//#define _1280x800_eDP_Panel_

#define _1_Port_	0x80
#define _2_Port_	0x00

#define _JEIDA_ 0x40
#define _VESA_	0x00

#define _Sync_Mode_ 0x00
#define _DE_Mode_	0x20

enum {
	hfp = 0,
	hs,
	hbp,
	hact,
	htotal,
	vfp,
	vs,
	vbp,
	vact,
	vtotal,
	pclk_10khz
};

static bool edp_idle_flag = 1;

u8			LVDS_Port;

//u16			V_act, H_act;

u16 h_fp, h_sync, h_bp, h_active, h_total, v_fp, v_sync, v_bp, v_active, v_total, P_clk;

u8	Read_DPCD010A = 0x00;

//u8			Read_DPCD000D = 0x00;

bool	ScrambleMode = 0;

bool	LVDS_unstable = 0;

//u8 eDP_Lane_num = 0x00;
//------------------------------------------------------
// for test

#define _gpio_sync_output_
#define sync_source 0x01    //gpio output lvds Rx sync
//#define sync_source 0x02 //gpio output lvds portA sync
//#define sync_source 0x03 //gpio output lvds portB sync

#ifdef _read_edid_          // read eDP panel EDID

u8		EDID_DATA[128] = { 0 };
u16		EDID_Timing[11] = { 0 };

bool	EDID_Reply = 0;
#endif

//------------------------------------------------------

// eDP data swap:
#define _eDP_data_PN_Swap_En	0xF0 // Please refer to the notes below
#define _eDP_data_PN_Swap_Dis	0x00

#define _eDP_data_PN_ _eDP_data_PN_Swap_Dis // defailt ; disable

/* eDP data P/N polarity swap 
bit7	RGD_MLCTRL_LANE3_RVSD_EN
		1 = data of lane3 polarity swap;
		0 = normal.

bit6	RGD_MLCTRL_LANE2_RVSD_EN
		1 = data of lane2 polarity swap;
		0 = normal.

bit5	RGD_MLCTRL_LANE1_RVSD_EN
		1 = data of lane1 polarity swap;
		0 = normal.

bit4	RGD_MLCTRL_LANE0_RVSD_EN
		1 = data of lane0 polarity swap;
		0 = normal.
//*/

//------------------------------------------//

#define _Lane0_data_	0
#define _Lane1_data_	1
#define _Lane2_data_	2
#define _Lane3_data_	3

#define _eDP_data_No_swap_	 0xe4 // default

#define _eDP_data3_select_	(_Lane3_data_ << 6) // default; _Lane3_data_select_ is lane3
#define _eDP_data2_select_	(_Lane2_data_ << 4) // default; _Lane2_data_select_ is lane2

#define _eDP_data1_select_	(_Lane1_data_ << 2)	// default; _Lane1_data_select_ is lane1
#define _eDP_data0_select_	(_Lane0_data_ << 0) // default; _Lane0_data_select_ is lane0

// example:lane1 and lane0 swap
//#define _eDP_data1_select_	(_Lane0_data_ << 2)	// default _Lane1_data_select_ is lane0
//#define _eDP_data0_select_	(_Lane1_data_ << 0) // default _Lane0_data_select_ is lane1


#define _eDP_data_sequence_ (_eDP_data3_select_ + _eDP_data2_select_ + _eDP_data1_select_ + _eDP_data0_select_)// _eDP_data_No_swap_


//===========================================//


// 有些eDP屏用eDP 加扰模式显示黑屏，屏蔽下面的宏定义，改成DP加扰模式。
//#define _eDP_scramble_ // eDP 加扰模式

//------------------------------------------------------

#ifdef _1080P_eDP_Panel_

#define _LVDS_Port_ _2_Port_

//根据前端LVDS 信号选择VESA或者JEIDA
#define _LVDS_RX_ _VESA_        // _JEIDA_

//根据前端LVDS 信号模式选择Sync模式或者是DE模式
#define _LVDS_Mode_ _DE_Mode_   // _Sync_Mode_ ; _DE_Mode

//根据前端LVDS信号的屏参，设置下面的Timing 数值.
static int LVDS_Timing[] =
// hfp,	hs,	hbp,	hact,	htotal,	vfp,	vs,	vbp,	vact,	vtotal,	pixel_CLK/10,000
//-----|---|------|-------|--------|-----|-----|-----|--------|--------|---------------
{ 88, 44, 148, 1920, 2200, 4, 5, 36, 1080, 1125, 14850 };


/*******************************************************************
   全志平台的屏参 lcd_hbp 是 上面参数 hbp + hs 的和；

   同样的，全志平台的屏参 lcd_vbp 是 上面参数 vbp + vs的 和，这点要注意。
*******************************************************************/

//#define	_6_bit_eDP_ // eDP panel Color Depth, 262K color
#define _8_bit_eDP_ // eDP panel Color Depth,16.7M color

// #define _8_to_6bit_Dither_En  // if Input 8 bit LVDS , Output is 6 bit eDP

#define _eDP_Lane_ 2

#endif

//-----------------------------------------------------//

#ifdef _1920x515_eDP_Panel_

#define _LVDS_Port_ _1_Port_

//根据前端LVDS 信号选择VESA或者JEIDA
//#define _LVDS_RX_ _JEIDA_       // _VESA_
#define _LVDS_RX_ _VESA_

//根据前端LVDS 信号模式选择Sync模式或者是DE模式
#define _LVDS_Mode_ _DE_Mode_   // _LVDS_Sync_Mode_ ; _LVDS_DE_Mode

// //根据前端LVDS信号的屏参，设置下面的Timing 数值.
// static int LVDS_Timing[] =
// // hfp,	hs,	hbp,	hact,	htotal,	vfp,	vs,	vbp,	vact,	vtotal,	pixel_CLK/10,000
// //-----|---|------|-------|--------|-----|-----|-----|--------|--------|---------------
// { 14, 56, 64, 1366, 1500, 1, 3, 28, 768, 800, 7400 };


/*******************************************************************
   全志平台的屏参 lcd_hbp 是 上面参数 hbp + hs 的和；

   同样的，全志平台的屏参 lcd_vbp 是 上面参数 vbp + vs的 和，这点要注意。
*******************************************************************/

//#define _6_bit_eDP_             // eDP panel Color Depth, 262K color

//#define _8_to_6bit_Dither_En    // if Input is 8 bit LVDS , Output is 6 bit eDP
#define _8_bit_eDP_ 

#define _eDP_Lane_ 1

#endif

#ifdef _1280x800_eDP_Panel_

#define _LVDS_Port_ _1_Port_

//根据前端LVDS 信号选择VESA或者JEIDA
#define _LVDS_RX_ _VESA_        // _VESA_ _JEIDA_

//根据前端LVDS 信号模式选择Sync模式或者是DE模式
#define _LVDS_Mode_ _DE_Mode_   // _LVDS_Sync_Mode_ ; _LVDS_DE_Mode

//根据前端LVDS信号的屏参，设置下面的Timing 数值.
static int LVDS_Timing[] =
// hfp,	hs,	hbp,	hact,	htotal,	vfp,	vs,	vbp,	vact,	vtotal,	pixel_CLK/10,000
//-----|---|------|-------|--------|-----|-----|-----|--------|--------|---------------
{ 48, 32, 80, 1280, 1440, 3, 6, 14, 800, 823, 7100 };


/*******************************************************************
   全志平台的屏参 lcd_hbp 是 上面参数 hbp + hs 的和；

   同样的，全志平台的屏参 lcd_vbp 是 上面参数 vbp + vs的 和，这点要注意。
*******************************************************************/

#define _6_bit_eDP_             // eDP panel Color Depth, 262K color

#define _8_to_6bit_Dither_En    // if Input is 8 bit LVDS , Output is 6 bit eDP

#define _eDP_Lane_ 1

#endif

#ifdef _1600x900_eDP_Panel_

#define _LVDS_Port_ _1_Port_

//根据前端LVDS 信号选择VESA或者JEIDA
#define _LVDS_RX_ _VESA_                                // _VESA_ _JEIDA_

//根据前端LVDS 信号模式选择Sync模式或者是DE模式
#define _LVDS_Mode_ _DE_Mode_                           // _LVDS_Sync_Mode_ ; _LVDS_DE_Mode

//根据前端LVDS信号的屏参，设置下面的Timing 数值.
static int LVDS_Timing[] =
// hfp,	hs,	hbp,	hact,	htotal,	vfp,	vs,	vbp,	vact,	vtotal,	pixel_CLK/10,000
//-----|---|------|-------|--------|-----|-----|-----|--------|--------|---------------

{ 48, 32, 260, 1600, 1940, 3, 5, 18, 900, 926, 8980 };  //


/*******************************************************************
   全志平台的屏参 lcd_hbp 是 上面参数 hbp + hs 的和；

   同样的，全志平台的屏参 lcd_vbp 是 上面参数 vbp + vs的 和，这点要注意。
*******************************************************************/

#define _6_bit_eDP_                                     // eDP panel Color Depth, 262K color

#define _8_to_6bit_Dither_En                            // if Input is 8 bit LVDS , Output is 6 bit eDP

#define _eDP_Lane_ 1

#endif


struct lt8911exb_data {
    struct i2c_client *client;
    int pwr_gpio;
    int rst_gpio;

    int hact;
    int vact;
    int hbp;
    int hfp;
    int hs;
    int vbp;
    int vfp;
    int vs;
    int pclk;
    int htotal;
    int vtotal;
    
    int lane_cnt;
    int mipi_lane;
    int color; //Color Depth 0:6bit 1:8bit
    int test;
};

#endif /*_LONTIUM_LT8911EXB_H_*/

